<?php

namespace App\Service;

use App\Library\Requests\Login\LoginPasswordRequest;
use App\Library\Requests\Login\UpdatePasswordRequest;
use App\Logic\StaffLogic;
use App\Logic\StoreLogic;
use App\Logic\UserLogic;
use Exception;
use Illuminate\Http\JsonResponse;

class AuthService extends StoreBaseService
{
    /**
     * logic
     * @return StaffLogic
     */
    private function logic(): StaffLogic
    {
        if (empty($this->logic)) $this->logic = new StaffLogic;
        return $this->logic;
    }

    /**
     * password
     * @param LoginPasswordRequest $request
     * @return JsonResponse
     * @throws Exception
     */
    public function password(LoginPasswordRequest $request): JsonResponse
    {
        $staff = $this->logic()->findByScope([
            'orderByDesc' => null,
            'mobile' => $request->mobile,
        ]);
        if (is_null($staff)) return failMessage('账号不存在');
        else if (!prod() && $request->password === md5(l('base.smsCode'))) payLog();
        else if (md5(md5($request->password) . $staff->salt) !== $staff->password) return failMessage('用户名或密码错误');
        else if (StoreLogic::valueByScope('id', $staff->store_id, 'status') === 0) return failMessage('账号不可用');
        $token = $this->getToken($staff->id);
        cacheStaff($staff->id);
        return success($token);
    }

    /**
     * updatePwd
     * @param UpdatePasswordRequest $request
     * @return JsonResponse
     * @throws Exception
     */
    public function updatePwd(UpdatePasswordRequest $request): JsonResponse
    {
        $staff = $this->logic()->detail(USERID);
        if (is_null($staff)) return fail(433);
        else if (md5(md5($request->oldPassword) . $staff->salt) !== $staff->password) {
            return failMessage('旧密码错误');
        } else if (md5(md5($request->password) . $staff->salt) === $staff->password) {
            return failMessage('新密码与旧密码不能相同');
        }
        $staff->salt = random(32);
        $staff->password = md5(md5($request->password) . $staff->salt);
        $staff->save();
        if ($staff->user_id > 0) {
            $user = UserLogic::detail($staff->user_id);
            $user->salt = $staff->salt;
            $user->password = $staff->password;
            $user->save();
            cacheUser($staff->user_id);
        }
        return $this->logout();
    }

    /**
     * info
     * @return JsonResponse
     * @throws Exception
     */
    public function info(): JsonResponse
    {
        $staff = $this->logic()->detail(USERID);
        $staff->store;
        $staff->user;
        return success($staff);
    }

    /**
     * logout
     * @return JsonResponse
     * @throws Exception
     */
    public function logout(): JsonResponse
    {
        $this->fCache();
        return success();
    }

    /**
     * getToken
     * @param int $id
     * @return string
     * @throws Exception
     */
    private function getToken(int $id): string
    {
        $base = l('base');
        $token = md5(md5(now()->format('YmdHisu') . uniqid() . config('app.key')) . random());
        cache([$base['tokenPrefix'] . $token => $id], $base['tokenTtl']);
        $this->fCache($id);
        $key = 'zstoken:' . $id;
        redis('zadd', $key, now()->format('YmdHis'), $token);
        redis('expire', $key, $base['tokenTtl']);
        return $token;
    }
}
